﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;

namespace Infrastructure.Base.Utils
{
    public class EnumHelper
    {
        public static List<KeyValuePair<T, string>> GetValueAndDescriptions<T>() where T : struct
        {
            return typeof (T).GetFields()
                .Where(item => item.IsStatic)
                .ToDictionary(item => (T) Enum.Parse(typeof (T), item.Name),
                    item =>
                        ((DescriptionAttribute) item.GetCustomAttributes(typeof (DescriptionAttribute), false)[0])
                            .Description)
                .ToList();
        }

        public static List<KeyValuePair<int, string>> GetValueAndDescriptions(Type @enum)
        {
            return @enum.GetFields()
                .Where(item => item.IsStatic)
                .ToDictionary(item => (int) Enum.Parse(@enum, item.Name),
                    item =>
                        ((DescriptionAttribute) item.GetCustomAttributes(typeof (DescriptionAttribute), false)[0])
                            .Description)
                .ToList();
        }

        public static List<string> GetDescriptions<T>() where T : struct
        {
            return typeof (T).GetFields()
                .Where(item => item.IsStatic)
                .Select(
                    item =>
                        ((DescriptionAttribute) item.GetCustomAttributes(typeof (DescriptionAttribute), false)[0])
                            .Description)
                .ToList();
        }

        public static List<T> GetValues<T>() where T : struct
        {
            return typeof (T).GetFields()
                .Where(item => item.IsStatic)
                .Select(item => (T) Enum.Parse(typeof (T), item.Name))
                .ToList();
        }

        public static string GetDescription<T>(int value) where T : struct
        {
            return typeof (T).GetFields()
                .Where(item => item.IsStatic)
                .Where(item =>
                    item.GetValue(null).GetHashCode() == value
                )
                .Select(
                    item =>
                        ((DescriptionAttribute) item.GetCustomAttributes(typeof (DescriptionAttribute), false)[0])
                            .Description)
                .FirstOrDefault();
        }

        public static T GetValue<T>(string description) where T : struct
        {
            return typeof (T).GetFields()
                .Where(item => item.IsStatic)
                .Where(
                    item =>
                        description ==
                        ((DescriptionAttribute) item.GetCustomAttributes(typeof (DescriptionAttribute), false)[0])
                            .Description)
                .Select(item => (T) Enum.Parse(typeof (T), item.Name))
                .FirstOrDefault();
        }

        public static string GetDescriptionByInt<T>(int? value) where T : struct
        {
            string d = typeof (T).GetFields()
                .Where(item => item.IsStatic)
                .Where(item => (int) Enum.Parse(typeof (T), item.Name) == value)
                .Select(
                    item =>
                        ((DescriptionAttribute)
                            item.GetCustomAttributes(typeof (DescriptionAttribute), false)[0]).Description)
                .FirstOrDefault();
            return d;
        }

        public static string GetDescriptionByInt(Type t, int? value)
        {
            return t.GetFields()
                .Where(item => item.IsStatic)
                .Where(item => (int) Enum.Parse(t, item.Name) == value)
                .Select(
                    item =>
                        ((DescriptionAttribute) item.GetCustomAttributes(typeof (DescriptionAttribute), false)[0])
                            .Description)
                .FirstOrDefault();
        }
    }
}